Match

#[derive(Debug)] // so we can inspect the state in a minute
enum UsState {
    Alabama,
    Alaska,
    // --snip--
}

enum Coin {
    Penny,
    Nickel,
    Dime,
    Quarter(UsState),
}

fn value_in_cents(coin: Coin) -> u8 {
    match coin {
        Coin::Penny => {
            println!("Lucky penny!");
            1
        }
        Coin::Nickel => 5,
        Coin::Dime => 10,
        Coin::Quarter(state) => {
            println!("State quarter from {state:?}!");
            25
        }
    }
}
  • Pattern :

    • The value Coin::Penny .

  • Separator :

    • =>  operator.

Examples

let x = 1;

match x {
    1 | 2 | 3 => println!("1 or 2 or 3");
    4..=8 => println!("from 4 to 8, including 8");
    'a'...='j' => println!("from a to j, including j");
    _ => println!("anything");
}

Exhaustiveness

  • If not all options are considered in the match, it will panic.

  • You can use the _  symbol to guarantee that all options are covered.

    let dice_roll = 9;
    match dice_roll {
        3 => add_fancy_hat(),
        7 => remove_fancy_hat(),
        _ => reroll(),
    }
    
    fn add_fancy_hat() {}
    fn remove_fancy_hat() {}
    fn reroll() {}
    
  • You can use the unit value   ()  to indicate that nothing happens in a branch:

    let dice_roll = 9;
    match dice_roll {
        3 => add_fancy_hat(),
        7 => remove_fancy_hat(),
        _ => (),
    }
    
    fn add_fancy_hat() {}
    fn remove_fancy_hat() {}
    

If Let

  • You can handle values that match one pattern while ignoring the rest.

let config_max = Some(3u8);
if let Some(max) = config_max {
    println!("The maximum is configured to be {max}");
}
  • What I understood is that if let  is basically treated like a new keyword, kinda....

  • I found it a bit confusing because it seems like I'm evaluating the return value of the operation let Some(max) , which doesn't make sense, considering let  doesn't return anything.